from fastapi import FastAPI, Request, status
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
from fastapi.staticfiles import StaticFiles
from contextlib import asynccontextmanager
import uvicorn
import os

from app.api import chat, files, conversations, audio, info
from app.core.config import settings
from app.core.exceptions import DifyAPIError, get_error_response
from app.core.logger import logger

# 定义lifespan上下文管理器
@asynccontextmanager
async def lifespan(app: FastAPI):
    """应用生命周期管理"""
    try:
        # 验证必要的配置参数
        settings.validate()
        logger.info(f"服务启动成功: {settings.APP_TITLE} v{settings.APP_VERSION}")
        yield
    except Exception as e:
        logger.error(f"服务启动失败: {str(e)}")
        # 重新抛出异常，终止应用
        raise

# 创建FastAPI应用实例
app = FastAPI(
    title=settings.APP_TITLE,
    description=settings.APP_DESCRIPTION,
    version=settings.APP_VERSION,
    docs_url="/docs" if settings.DEBUG else None,  # 在生产环境中禁用docs
    redoc_url="/redoc" if settings.DEBUG else None,  # 在生产环境中禁用redoc
    lifespan=lifespan
)

# 添加CORS中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # 允许所有来源，生产环境中应该限制
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 注册路由
app.include_router(chat.router)
app.include_router(files.router)
app.include_router(conversations.router)
app.include_router(audio.router)
app.include_router(info.router)

# 挂载静态文件目录
static_dir = os.path.join(os.getcwd(), "static")
if not os.path.exists(static_dir):
    os.makedirs(static_dir)
    logger.info(f"创建静态文件目录: {static_dir}")
app.mount("/static", StaticFiles(directory=static_dir), name="static")

# 异常处理
@app.exception_handler(DifyAPIError)
async def dify_api_exception_handler(request: Request, exc: DifyAPIError):
    """处理Dify API异常"""
    logger.error(f"Dify API错误: {exc.detail}")
    return JSONResponse(
        status_code=exc.status_code,
        content=get_error_response(exc)
    )

@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
    """处理请求验证异常"""
    logger.error(f"请求验证错误: {str(exc)}")
    return JSONResponse(
        status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
        content={
            "status": "error",
            "message": "请求数据验证失败",
            "detail": exc.errors()
        }
    )

@app.exception_handler(Exception)
async def general_exception_handler(request: Request, exc: Exception):
    """处理一般异常"""
    logger.error(f"服务器错误: {str(exc)}", exc_info=True)
    return JSONResponse(
        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
        content={
            "status": "error",
            "message": "服务器内部错误",
            "detail": str(exc) if settings.DEBUG else "请联系管理员"
        }
    )

# 根路由
@app.get("/")
async def root():
    """API根路径"""
    return {
        "name": settings.APP_TITLE,
        "version": settings.APP_VERSION,
        "description": settings.APP_DESCRIPTION,
        "docs": "/docs" if settings.DEBUG else None,
        "test_pages": {
            "文本转语音测试": "/static/audio_test.html"
        }
    }

# 健康检查
@app.get("/health")
async def health_check():
    """健康检查接口"""
    return {"status": "ok"}

# 当直接运行此文件时启动应用
if __name__ == "__main__":
    uvicorn.run(
        "app.main:app",
        host=settings.APP_HOST,
        port=settings.APP_PORT,
        reload=settings.DEBUG
    )
